package com.excemly.library.service;

import org.springframework.data.domain.PageRequest;

import com.excemly.library.entity.Book;
import com.excemly.library.repository.BookRepository;
import com.excemly.library.service.BorrowService;
import com.excemly.library.entity.Borrow;
import com.excemly.library.exceptions.ResourceNotFoundException;
import com.excemly.library.exceptions.InsufficientStockException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
/**
 * 图书业务逻辑类，提供完整的图书管理功能
 * 包括图书的增删改查、搜索、借阅和热门图书查询等功能
 */
import jakarta.persistence.criteria.Predicate;
import jakarta.validation.Valid;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.PageImpl;
import java.util.Collections;
import java.util.ArrayList;
import java.util.List;
import java.util.List;

@Service
public class BookService {

    private final BookRepository bookRepository;
    private final BorrowService borrowService;

    public BookService(BookRepository bookRepository, BorrowService borrowService) {
        this.bookRepository = bookRepository;
        this.borrowService = borrowService;
    }

    public Page<Book> searchBooks(String title, String author, String isbn, Pageable pageable) {

        if ((title == null || title.isEmpty()) && (author == null || author.isEmpty())
                && (isbn == null || isbn.isEmpty())) {
            return new PageImpl<>(Collections.emptyList(), pageable, 0);
        }
        Specification<Book> spec = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (title != null && !title.isEmpty()) {
                predicates.add(cb.like(root.get("title"), "%" + title + "%"));
            }
            if (author != null && !author.isEmpty()) {
                predicates.add(cb.like(root.get("author"), "%" + author + "%"));
            }
            if (isbn != null && !isbn.isEmpty()) {
                predicates.add(cb.like(root.get("isbn"), "%" + isbn + "%"));
            }
            return cb.and(predicates.toArray(new Predicate[0]));
        };
        return bookRepository.findAll(spec, pageable);
    }

    @Transactional
    public Book saveBook(@Valid Book book) {
        if (book.getAvailableCopies() < 0) {
            throw new IllegalArgumentException("Book stock cannot be negative");
        }
        if (book.getTitle() == null || book.getTitle().isEmpty()) {
            throw new IllegalArgumentException("Book title cannot be empty");
        }
        if (book.getAuthor() == null || book.getAuthor().isEmpty()) {
            throw new IllegalArgumentException("Book author cannot be empty");
        }
        if (book.getIsbn() == null || book.getIsbn().isEmpty()) {
            throw new IllegalArgumentException("Book ISBN cannot be empty");
        }
        return bookRepository.save(book);
    }

    public Book getBookById(Long id) {
        if (id == null) {
            throw new IllegalArgumentException("Book ID cannot be null");
        }
        return bookRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("Book not found with id: " + id));
    }

    @Transactional
    public Book updateBook(Long id, @Valid Book bookDetails) {
        if (bookDetails.getAvailableCopies() < 0) {
            throw new IllegalArgumentException("Book stock cannot be negative");
        }
        if (bookDetails.getTitle() == null || bookDetails.getTitle().isEmpty()) {
            throw new IllegalArgumentException("Book title cannot be empty");
        }
        if (bookDetails.getAuthor() == null || bookDetails.getAuthor().isEmpty()) {
            throw new IllegalArgumentException("Book author cannot be empty");
        }
        if (bookDetails.getIsbn() == null || bookDetails.getIsbn().isEmpty()) {
            throw new IllegalArgumentException("Book ISBN cannot be empty");
        }
        Book book = bookRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("Book not found with id: " + id));
        book.setTitle(bookDetails.getTitle());
        book.setAuthor(bookDetails.getAuthor());
        book.setIsbn(bookDetails.getIsbn());
        book.setPublishDate(bookDetails.getPublishDate());
        book.setAvailableCopies(bookDetails.getAvailableCopies() + book.getAvailableCopies());
        return bookRepository.save(book);
    }

    @Transactional
    public void deleteBook(Long id) {
        Book book = bookRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("Book not found with id: " + id));
        bookRepository.delete(book);
    }

    public List<Book> getHotBooks(int page, int pageSize) {
        // 根据分页参数查询借阅次数最多的图书及其借阅次数
        List<Object[]> results = bookRepository.findByBorrowCount(PageRequest.of(page - 1, pageSize));
        List<Book> hotBooks = new ArrayList<>();

        for (Object[] result : results) {
            Book book = (Book) result[0];
            Long borrowCount = (Long) result[1];
            book.setBorrowCount(borrowCount.intValue()); // 转换为Integer类型
            // 设置封面图片URL，假设图片文件名为书名.jpg
            // 增强标题空值检查，处理空白字符串并添加日志
            System.out.println("原始标题值: Book ID=" + book.getId() + ", Title='" + book.getTitle() + "'");
            if (book.getTitle() == null || book.getTitle().trim().isEmpty()) {
                book.setTitle("未知书名");
                System.out.println("已修正空标题: Book ID=" + book.getId());
            }
            book.setCoverUrl("/book-covers/" + book.getId() + ".jpg");
            hotBooks.add(book);
        }

        return hotBooks;
    }

    @Transactional
    public void borrowBook(Long bookId, Long userId) {
        // 委托给BorrowService处理借阅逻辑
        borrowService.borrowBook(bookId, userId);
    }
}